﻿using System;
using VsxFactory.Modeling.VisualStudio;

namespace VsxFactory.Modeling.Strategies.VisualStudio
{
    [System.Diagnostics.DebuggerDisplay("Project : Name={Name}")]
    internal class VSProject : VSContainer, IVsProject
    {
        private ProjectNode projectNode;

        internal VSProject(IVsSolution solution, ProjectNode projectNode) : base(solution, projectNode)
        {
            System.Diagnostics.Contracts.Contract.Requires(solution != null);
            System.Diagnostics.Contracts.Contract.Requires(projectNode != null);

            this.projectNode = projectNode;
        }

        public string Path
        {
            get { return node.ProjectDir; }
        }

        public Guid ProjectGuid
        {
            get { return node.ProjectGuid; }
        }

        public IVsProjectFileItem AddFromTemplate(string templateName, string fileName, bool overwrite)
        {
            System.Diagnostics.Contracts.Contract.Requires(!String.IsNullOrWhiteSpace(templateName));
            System.Diagnostics.Contracts.Contract.Requires(!String.IsNullOrWhiteSpace(fileName));

            string relativeFileName = Utils.PathRelativePathToFolder(node.ProjectDir, fileName);
            var hn = projectNode.AddFromTemplate(templateName, relativeFileName, overwrite);
            return new VSProjectItem(this, hn);
        }

        public IVsProjectFileItem AddFromFile(string relativeFileName)
        {
            System.Diagnostics.Contracts.Contract.Requires(!String.IsNullOrWhiteSpace(relativeFileName));

            node.EnsureCheckout();
            var hn = projectNode.AddItem(relativeFileName);
            return new VSProjectItem(this, hn);
        }

        public string Name
        {
            get
            {
                return projectNode.Name;
            }
            set
            {
                projectNode.Name = value;
            }
        }

        public string Namespace 
        {
            get { return projectNode.Namespace; } 
        }

        public void Remove()
        {
            node.Remove();
        }

        public void RemoveItem(string relativeFileName)
        {
            System.Diagnostics.Contracts.Contract.Requires(!String.IsNullOrWhiteSpace(relativeFileName));

            projectNode.RemoveItem(relativeFileName);
        }

        public void RenameItem(string oldRelativeFileName, string newRelativeFileName)
        {
            System.Diagnostics.Contracts.Contract.Requires(!String.IsNullOrWhiteSpace(oldRelativeFileName));
            System.Diagnostics.Contracts.Contract.Requires(!String.IsNullOrWhiteSpace(newRelativeFileName));

            projectNode.RenameItem(oldRelativeFileName, newRelativeFileName);
        }

        public IVsProjectFileItem AddItem(string fullName)
        {
            System.Diagnostics.Contracts.Contract.Requires(!String.IsNullOrWhiteSpace(fullName));

            var hn = projectNode.AddItem(fullName);
            return new VSProjectItem(this, hn);
        }

        public ProjectKind Kind
        {
            get
            {
                return projectNode.Kind;
            }
        }

        public string Language
        {
            get
            {
                return projectNode.Language;
            }
        }

        public IVsProjectFileItem AddItem(string fileName, byte[] content=null)
        {
            System.Diagnostics.Contracts.Contract.Requires(!String.IsNullOrWhiteSpace(fileName));
            var pi = ((ProjectNode)node).AddItem(fileName, content);
            return pi != null ? new VSProjectItem(this, pi) : null;
        }

        public void AddItemAsLink(string fileName)
        {
            System.Diagnostics.Contracts.Contract.Requires(!String.IsNullOrWhiteSpace(fileName));
            ((ProjectNode)node).AddItemAsLink(fileName);
        }

        public IVsFolder FindOrCreateFolder(string folderName)
        {
            System.Diagnostics.Contracts.Contract.Requires(!String.IsNullOrWhiteSpace(folderName));
            var folder = ((ProjectNode)node).FindOrCreateFolder(folderName);
            if (folder == null)
                return null;
            return new VSFolder(this.Solution, folder);
        }

        public IVsProjectReference AddProjectReference(Guid projectGuid)
        {
            System.Diagnostics.Contracts.Contract.Requires(projectGuid != Guid.Empty);
            projectNode.AddProjectReference(projectGuid);
            return new VSReference(this.Solution, projectGuid );
        }

        public IVsProjectReference AddReference(string assemblyName, string version = null)
        {
            System.Diagnostics.Contracts.Contract.Requires(!String.IsNullOrWhiteSpace(assemblyName));
            projectNode.AddAssemblyReference(assemblyName, version);
            return new VSReference(this.Solution, assemblyName, version);
        }
    }
}
